package com.gpframework.module.process.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gpframework.common.core.domain.AjaxResult;
import com.gpframework.common.enums.YesNoEnum;
import com.gpframework.common.utils.DateUtils;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.module.manufacture.domain.GpProductionDetails;
import com.gpframework.module.manufacture.domain.req.GpProductionDetailsUpdate;
import com.gpframework.module.manufacture.service.IGpProductionDetailsService;
import com.gpframework.module.module.domain.GpIncomingInspect;
import com.gpframework.module.module.domain.GpIncomingInspectWeight;
import com.gpframework.module.module.domain.GpIncomingInspectWidth;
import com.gpframework.module.module.domain.GpIncomingInspectYardVerify;
import com.gpframework.module.module.service.IGpIncomingInspectService;
import com.gpframework.module.process.domain.*;
import com.gpframework.module.process.domain.req.GpProcessDeliveryNoteUpdate;
import com.gpframework.module.process.service.*;
import net.bytebuddy.implementation.bytecode.Throw;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.module.process.mapper.GpProcessDeliveryNoteMapper;
import com.gpframework.module.process.domain.vo.GpProcessDeliveryNoteVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @ClassName GpProcessDeliveryNote
 * @Author gpframework
 * @Date 2023-12-20
 * @Version 1.0.0
 * @Description 加工到货单Service业务层处理
 */
@Service
public class GpProcessDeliveryNoteServiceImpl extends ServiceImpl<GpProcessDeliveryNoteMapper, GpProcessDeliveryNote> implements IGpProcessDeliveryNoteService {



    @Autowired
    private IGpProcessManagementService iGpProcessManagementService;

    @Autowired
    private IGpProcessSchedulingService iGpProcessSchedulingService;

    @Autowired
    private IGpProcessOverflowRateService iGpProcessOverflowRateService;

    @Autowired
    private  IGpBackerPriceService iGpBackerPriceService;

    @Autowired
    private IGpProcessCostingService iGpProcessCostingService;

    @Autowired
    private IGpProductionDetailsService iGpProductionDetailsService;

    @Autowired
    private IGpProcessIncomingInspectService iGpProcessIncomingInspectService;

    @Autowired
    private IGpProcessIncomingInspectYardVerifyService iGpProcessIncomingInspectYardVerifyService;

    @Autowired
    private IGpProcessIncomingInspectWidthService iGpProcessIncomingInspectWidthService;

    @Autowired
    private IGpProcessIncomingInspectFormaldehydeService iGpProcessIncomingInspectFormaldehydeService;




    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2023-12-20
     * @Param [lqw]
     * @Return List<GpProcessDeliveryNoteVo>
     */
    @Override
    public List<GpProcessDeliveryNoteVo> listVo(QueryWrapper<GpProcessDeliveryNote> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2023-12-20
     * @Param [id]
     * @Return GpProcessDeliveryNoteVo
     */
    @Override
    public GpProcessDeliveryNoteVo getVoById(Long id) {
        return this.baseMapper.getVo(id);
    }


    @Override
    public boolean edit(List<GpProcessDeliveryNoteUpdate> gpProcessDeliveryNoteUpdates) {
        List<GpProcessDeliveryNote> updateList = new ArrayList<>();
        for (GpProcessDeliveryNoteUpdate gpProcessDeliveryNoteUpdate : gpProcessDeliveryNoteUpdates) {
            GpProcessDeliveryNote gpProcessDeliveryNote = Convert.convert(new TypeReference<GpProcessDeliveryNote>() {}, gpProcessDeliveryNoteUpdate);
            updateProcessScheduling(gpProcessDeliveryNote);
            calculate(gpProcessDeliveryNote);
            updateList.add(gpProcessDeliveryNote);
        }
        return this.updateBatchById(updateList);
    }

    private void updateProcessScheduling(GpProcessDeliveryNote gpProcessDeliveryNote) {
        //更新排单表的数据
        GpProcessScheduling gpProcessScheduling = iGpProcessSchedulingService.getById(gpProcessDeliveryNote.getProcessSchedulingId());
        gpProcessScheduling.setProcessor(gpProcessDeliveryNote.getProcessor());
        gpProcessScheduling.setProductColor(gpProcessDeliveryNote.getProductColor());
        gpProcessScheduling.setProductName(gpProcessDeliveryNote.getProductName());
        iGpProcessSchedulingService.updateById(gpProcessScheduling);

    }

    @Override
    public boolean createOverflowRate(GpProcessDeliveryNoteUpdate gpProcessDeliveryNoteUpdates) {
        ArrayList<GpProcessOverflowRate> gpProcessOverflowRateArrayList = new ArrayList<>();
        List<Long> ids = gpProcessDeliveryNoteUpdates.getIds();
        for (Long id : ids) {
            GpProcessOverflowRate gpProcessOverflowRate = new GpProcessOverflowRate();
            GpProcessDeliveryNote gpProcessDeliveryNote = this.getById(id);


            if (StringUtils.isNotBlank(gpProcessDeliveryNoteUpdates.getCreateBy())) {
                gpProcessOverflowRate.setCreateBy(gpProcessDeliveryNoteUpdates.getCreateBy());
            }
            gpProcessOverflowRate.setProductionApplicationId(gpProcessDeliveryNote.getProductionApplicationId());
            gpProcessOverflowRate.setProcessSchedulingId(gpProcessDeliveryNote.getProcessSchedulingId());
            gpProcessOverflowRate.setProcessDeliveryNoteId(gpProcessDeliveryNote.getId());

            gpProcessOverflowRate.setSn(gpProcessDeliveryNote.getSn());
            gpProcessOverflowRate.setProcessor(gpProcessDeliveryNote.getProcessor());
            gpProcessOverflowRate.setBatchNo(gpProcessDeliveryNote.getDyeVatNo());


            GpProcessScheduling gpProcessScheduling = iGpProcessSchedulingService.getById(gpProcessDeliveryNote.getProcessSchedulingId());
            if (gpProcessScheduling!=null){
                gpProcessOverflowRate.setBackerName(gpProcessScheduling.getBackerName());
                gpProcessOverflowRate.setBackerColor(gpProcessScheduling.getBackerColor());
            }


            if (gpProcessDeliveryNote.getTotalSizeSufficient() != null) {
                gpProcessOverflowRate.setProductReturn(new BigDecimal(gpProcessDeliveryNote.getTotalSizeSufficient()));
            }

            gpProcessOverflowRate.setProductName(gpProcessDeliveryNote.getProductName());
            gpProcessOverflowRate.setProductColor(gpProcessDeliveryNote.getProductColor());
            gpProcessOverflowRate.setDocumentaryId(gpProcessDeliveryNote.getDocumentaryId());
            gpProcessOverflowRate.setDocumentaryMan(gpProcessDeliveryNote.getDocumentaryMan());
            gpProcessOverflowRateArrayList.add(gpProcessOverflowRate);

        }
        return iGpProcessOverflowRateService.saveBatch(gpProcessOverflowRateArrayList);
    }


    @Override
    public boolean createCostCalculate(GpProcessDeliveryNoteUpdate gpProcessDeliveryNoteUpdates) {
        ArrayList<GpProcessCosting> gpProcessCostings = new ArrayList<>();
        List<Long> ids = gpProcessDeliveryNoteUpdates.getIds();
        for (Long id : ids) {
            GpProcessCosting gpProcessCosting = new GpProcessCosting();
            GpProcessDeliveryNote gpProcessDeliveryNote = this.getById(id);

            if (StringUtils.isNotBlank(gpProcessDeliveryNoteUpdates.getCreateBy())) {
                gpProcessCosting.setCreateBy(gpProcessDeliveryNoteUpdates.getCreateBy());
            }
            gpProcessCosting.setProductionApplicationId(gpProcessDeliveryNote.getProductionApplicationId());
            gpProcessCosting.setProcessSchedulingId(gpProcessDeliveryNote.getProcessSchedulingId());

            gpProcessCosting.setSn(gpProcessDeliveryNote.getSn());
            gpProcessCosting.setProductName(gpProcessDeliveryNote.getProductName());
            gpProcessCosting.setProductColor(gpProcessDeliveryNote.getProductColor());

            gpProcessCosting.setBatchNo(gpProcessDeliveryNote.getDyeVatNo());
            gpProcessCosting.setProcessor(gpProcessDeliveryNote.getProcessor());
            gpProcessCosting.setCodingSpecificationsEmpty(new BigDecimal(gpProcessDeliveryNote.getCodingSpecificationsEmpty()));
            gpProcessCosting.setCodingSpecificationsSufficient(new BigDecimal(gpProcessDeliveryNote.getCodingSpecificationsSufficient()));
            if (gpProcessDeliveryNote.getSizeBar()!=null)
            gpProcessCosting.setSizeBar((gpProcessDeliveryNote.getSizeBar().intValue()));

            GpProcessScheduling gpProcessScheduling = iGpProcessSchedulingService.getById(gpProcessDeliveryNote.getProcessSchedulingId());
            if (gpProcessScheduling!=null) {
                gpProcessCosting.setBackerName(gpProcessScheduling.getBackerName());
                gpProcessCosting.setBackerColor(gpProcessScheduling.getBackerColor());
            }

            GpBackerPrice gpBackerPrice = iGpBackerPriceService.getOne(new LambdaQueryWrapper<GpBackerPrice>()
                    .eq(GpBackerPrice::getBacker, gpProcessCosting.getBackerName())
                    .eq(GpBackerPrice::getCharacteristic,gpProcessCosting.getCharacteristic())
                    .eq(GpBackerPrice::getDelStatus, YesNoEnum.NO.getKey())
                    .last("limit 1"));
            if (gpBackerPrice != null) {
                gpProcessCosting.setBackerPrice(gpBackerPrice.getBackerPrice());
                gpProcessCosting.setProcessFee(gpBackerPrice.getProcessFee());
                gpProcessCosting.setCharacteristic(gpBackerPrice.getCharacteristic());
            }
            gpProcessCostings.add(gpProcessCosting);

        }
        return iGpProcessCostingService.saveBatch(gpProcessCostings);
    }

    @Override
    @Transactional
    public boolean createProcessingIncomingInspection(GpProcessDeliveryNoteUpdate gpProcessDeliveryNoteUpdates){
        ArrayList<GpProcessIncomingInspect> gpProcessIncomingInspects = new ArrayList<>();
        List<Long> ids = gpProcessDeliveryNoteUpdates.getIds();
        for (Long id : ids) {
            GpProcessDeliveryNote gpProcessDeliveryNote = this.getById(id);
            gpProcessDeliveryNote.setIncomingFlag(YesNoEnum.YES.getKey());
            this.updateById(gpProcessDeliveryNote);
            GpProcessIncomingInspect gpProcessIncomingInspect = Convert.convert(new TypeReference<GpProcessIncomingInspect>() {
            }, gpProcessDeliveryNote);
            if (StringUtils.isNotBlank(gpProcessDeliveryNoteUpdates.getCreateBy())) {
                gpProcessIncomingInspect.setCreateBy(gpProcessDeliveryNoteUpdates.getCreateBy());
            }

            if(gpProcessDeliveryNote.getCodingSpecificationsEmpty()!=null){
                gpProcessIncomingInspect.setStandardCodeEmpty(gpProcessDeliveryNote.getCodingSpecificationsEmpty().intValue());
            }
            if (gpProcessDeliveryNote.getCodingSpecificationsSufficient()!=null){
                gpProcessIncomingInspect.setStandardCodeSufficient(gpProcessDeliveryNote.getCodingSpecificationsSufficient().intValue());
            }

            gpProcessIncomingInspect.setSn(getSn());

            //批号
            gpProcessIncomingInspect.setBatchNo(gpProcessDeliveryNote.getDyeVatNo());
            GpProcessScheduling processScheduling = iGpProcessSchedulingService.getById(gpProcessIncomingInspect.getProcessSchedulingId());
            gpProcessIncomingInspect.setIncomingTime(processScheduling.getSchedulingDate());

            //到货单id
            gpProcessIncomingInspect.setProcessDeliveryNoteId(gpProcessDeliveryNote.getId());

            //同步做货明细跟单员
            gpProcessIncomingInspect.setDocumentaryId(gpProcessDeliveryNote.getDocumentaryId());
            gpProcessIncomingInspect.setDocumentaryMan(gpProcessDeliveryNote.getDocumentaryMan());

            gpProcessIncomingInspects.add(gpProcessIncomingInspect);

        }
        boolean saveBatch =iGpProcessIncomingInspectService.saveBatch(gpProcessIncomingInspects);
        if (saveBatch) {
            this.createSubList(gpProcessIncomingInspects);
        }

        return saveBatch;
    }

    private void createSubList(ArrayList<GpProcessIncomingInspect> gpProcessIncomingInspects) {
        for (GpProcessIncomingInspect gpProcessIncomingInspect : gpProcessIncomingInspects) {
            GpProcessIncomingInspectYardVerify gpProcessIncomingInspectYardVerify;
            GpProcessIncomingInspectWidth gpProcessIncomingInspectWidth;
            for (int i = 0; i < 5; i++) {
                gpProcessIncomingInspectYardVerify = new GpProcessIncomingInspectYardVerify();
                gpProcessIncomingInspectYardVerify.setIncomingInspectId(gpProcessIncomingInspect.getId());
                iGpProcessIncomingInspectYardVerifyService.save(gpProcessIncomingInspectYardVerify);
            }
            for (int i = 0; i < 6; i++) {
                GpProcessIncomingInspectFormaldehyde gpProcessIncomingInspectFormaldehyde = new GpProcessIncomingInspectFormaldehyde();
                gpProcessIncomingInspectFormaldehyde.setIncomingInspectId(gpProcessIncomingInspect.getId());
                iGpProcessIncomingInspectFormaldehydeService.save(gpProcessIncomingInspectFormaldehyde);

            }

            for (int i = 0; i < 3; i++) {
                gpProcessIncomingInspectWidth = new GpProcessIncomingInspectWidth();
                gpProcessIncomingInspectWidth.setIncomingInspectId(gpProcessIncomingInspect.getId());
                iGpProcessIncomingInspectWidthService.save(gpProcessIncomingInspectWidth);
            }

        }



    }

    @Override
    public boolean editOne(GpProcessDeliveryNoteUpdate gpProcessDeliveryNoteUpdate) {
        GpProcessDeliveryNote gpProcessDeliveryNote = Convert.convert(new TypeReference<GpProcessDeliveryNote>() {}, gpProcessDeliveryNoteUpdate);
        calculate(gpProcessDeliveryNote);

        return this.updateById(gpProcessDeliveryNote);
    }

    @Override
    public boolean copy(Long id, Integer copyNum) {
        GpProcessDeliveryNote gpProcessDeliveryNote = this.getById(id);
        if (gpProcessDeliveryNote == null) {
            return false;
        }
        for (int i = 0; i < copyNum; i++) {
            gpProcessDeliveryNote.setId(null);
            this.save(gpProcessDeliveryNote);
        }
        return true;
    }

    //计算到货单数据
    public void calculate(GpProcessDeliveryNote gpProcessDeliveryNote) {
        GpProcessManagement gpProcessManagement = new GpProcessManagement();
        if (StringUtils.isBlank(gpProcessDeliveryNote.getDyeVatNo())) {
            gpProcessManagement = iGpProcessManagementService.getOne(new QueryWrapper<GpProcessManagement>().eq("processor",gpProcessDeliveryNote.getProcessor()).eq("del_status",YesNoEnum.NO.getKey()).last("limit 1"));
            if (gpProcessManagement != null && gpProcessManagement.getProcessorCode() != null) {
                gpProcessDeliveryNote.setDyeVatNo(gpProcessManagement.getProcessorCode() + DateUtils.getDate());
            } else {
                gpProcessDeliveryNote.setDyeVatNo(DateUtils.getDate());
            }
        }

        if ( gpProcessDeliveryNote.getNumberItems() ==null || gpProcessDeliveryNote.getSizeBar() ==null || gpProcessDeliveryNote.getPackNum()==null){
            return;
        }
        Long numberItems = gpProcessDeliveryNote.getNumberItems();
        Long sizeBar = gpProcessDeliveryNote.getSizeBar();
        Long codingSpecificationsEmpty = gpProcessDeliveryNote.getCodingSpecificationsEmpty();
        Long codingSpecificationsSufficient = gpProcessDeliveryNote.getCodingSpecificationsSufficient();

        if (sizeBar>0){
            gpProcessDeliveryNote.setTotalSizeEmpty((numberItems - 1)*codingSpecificationsEmpty+sizeBar);
            gpProcessDeliveryNote.setTotalSizeSufficient((numberItems - 1)*codingSpecificationsSufficient+sizeBar);
        }else {
            gpProcessDeliveryNote.setTotalSizeEmpty((numberItems*codingSpecificationsEmpty));
            gpProcessDeliveryNote.setTotalSizeSufficient((numberItems*codingSpecificationsSufficient));
        }

    }

    /**
     * 获取生成加工订单号
     */
    private String getSn() {
        String sn = "";

        String yyMMdd = DateUtils.getDate("yyMMdd");
        sn += yyMMdd;

        GpProcessScheduling processScheduling = iGpProcessSchedulingService.getOne(new LambdaQueryWrapper<GpProcessScheduling>()
                .eq(GpProcessScheduling::getDelStatus, YesNoEnum.NO.getKey())
                .isNotNull(GpProcessScheduling::getSn)
                .gt(GpProcessScheduling::getCreateTime, DateUtils.getDate("yyyy-MM-dd 00:00:00"))
                .orderByDesc(GpProcessScheduling::getCreateTime)
                .last("limit 1"));
        if (processScheduling == null) {
            sn += "-1";
        } else {
            sn += processScheduling.getSn().substring(processScheduling.getSn().lastIndexOf("-"));
        }
        return sn;
    }

}
